package com.amigo.online.provider.video.controller;

import java.util.ArrayList;
import java.util.List;

import javax.annotation.Resource;

import org.apache.catalina.servlet4preview.http.HttpServletRequest;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.alibaba.fastjson.JSONObject;
import com.amigo.online.common.base.controller.BaseController;
import com.amigo.online.common.base.security.LocalUser;
import com.amigo.online.common.core.response.Response;
import com.amigo.online.common.core.response.StatusCode;
import com.amigo.online.common.core.security.IgnoreSecurity;
import com.amigo.online.common.param.common.MqTag;
import com.amigo.online.common.param.dto.video.AddWaterMarkDto;
import com.amigo.online.common.param.dto.video.LookVideoDto;
import com.amigo.online.common.param.dto.video.RecommendVideoDto;
import com.amigo.online.common.param.dto.video.ShareVideoDto;
import com.amigo.online.common.param.dto.video.VideoCommentDto;
import com.amigo.online.common.param.dto.video.VideoDto;
import com.amigo.online.common.param.dto.video.VideoQueryDto;
import com.amigo.online.common.param.result.LocalUserInfo;
import com.amigo.online.common.param.result.VideoInfo;
import com.amigo.online.common.param.result.VideoWhoSawMeInfo;
import com.amigo.online.common.util.CommonValidator;
import com.amigo.online.provider.video.common.GlobalController;
import com.amigo.online.provider.video.exception.MusicException;
import com.amigo.online.provider.video.exception.VideoException;
import com.amigo.online.provider.video.model.entity.VideoComment;
import com.amigo.online.provider.video.rocketmq.RocketMqUtil;
import com.amigo.online.provider.video.rocketmq.model.BaseMqSendModel;
import com.amigo.online.provider.video.service.MusicService;
import com.amigo.online.provider.video.service.RecommendVideoService;
import com.amigo.online.provider.video.service.UserFeignService;
import com.amigo.online.provider.video.service.VideoService;


/**
 * 视频相关
 *
 * @author amigo
 */

@RestController
@RequestMapping(value = "/video", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
public class VideoController extends BaseController {

    @Resource
    private VideoService videoService;

    @Resource
    private MusicService musicService;

    @Resource
    private RecommendVideoService recommendVideoService;

    @Resource
    private UserFeignService userFeignService;

    @PostMapping(value = "/new")
    public ResponseEntity<Response> newUserVideo(@RequestBody VideoDto dto) {
        if (!CommonValidator.validate(dto)) {
            throw new VideoException(StatusCode.BAD_REQUEST);
        }
        VideoInfo video = videoService.newUserVideo(dto);

        //solr数据同步
//		RocketMqUtil.send(MqTag.ROCKETMQ_BEAN_VIDEOTOSOLR, video, MqTag.SEARCH);
        JSONObject rs = new JSONObject();
        rs.put("videoId", video.getId());
        rs.put("cover", video.getCover());
        return success(rs);
    }

    @IgnoreSecurity
    @CrossOrigin
    @GetMapping(value = "/info/{id}")
    public ResponseEntity<Response> getVideoInfoById(@PathVariable Long id) {
        if (id == null || id <= 0) {
            throw new VideoException(StatusCode.BAD_REQUEST);
        }
        VideoInfo video = videoService.getVideoInfoById(id);
        return success(video);
    }

    /**
     * 保存视频观看纪录(已登录)
     *
     * @param id
     * @param lookTime
     * @return
     */
    @PostMapping(value = "/look/{id}/{lookTime}")
    public ResponseEntity<Response> lookVideoById(@PathVariable Long id, @PathVariable Long lookTime) {
        if (id == null || id <= 0 || lookTime == null || lookTime <= 0) {
            throw new VideoException(StatusCode.BAD_REQUEST);
        }
        return success(videoService.lookVideoById(id, lookTime));
    }

    /**
     * 保存视频观看纪录(已登录)
     *
     * @param lookVideoDto
     * @return
     */
    @PostMapping(value = "/look")
    public ResponseEntity<Response> lookVideoById2(@RequestBody LookVideoDto lookVideoDto) {
        if (lookVideoDto.getVideoId() == null || lookVideoDto.getVideoId() <= 0 || lookVideoDto.getLookTime() == null ||
                lookVideoDto.getLookTime() <= 0) {
            throw new VideoException(StatusCode.BAD_REQUEST);
        }

        return success(videoService.lookVideoById(lookVideoDto.getVideoId(), lookVideoDto.getLookTime()));
    }

    /**
     * 保存视频观看纪录(未登录)
     *
     * @param lookVideoDto
     * @return
     */
    @IgnoreSecurity
    @PostMapping(value = "/lookNotLogined")
    public ResponseEntity<Response> lookVideoNotLogined(@RequestBody LookVideoDto lookVideoDto) {
        if (lookVideoDto.getVideoId() == null || lookVideoDto.getVideoId() <= 0 || lookVideoDto.getLookTime() == null ||
                lookVideoDto.getLookTime() <= 0) {
            throw new VideoException(StatusCode.BAD_REQUEST);
        }
        return success(videoService.lookVideoNotLogined(lookVideoDto.getVideoId(), lookVideoDto.getLookTime(), lookVideoDto.getDeviceId()));
    }


    /**
     * 视频观看接口V3版本
     *
     * @param lookVideoDto
     * @return
     */
    @PostMapping(value = "/v3/look")
    @IgnoreSecurity
    public ResponseEntity<Response> lookVideoByIdV3(@RequestBody LookVideoDto lookVideoDto) {
        if (lookVideoDto.getVideoId() == null || lookVideoDto.getVideoId() <= 0 || lookVideoDto.getLookTime() == null ||
                lookVideoDto.getLookTime() <= 0) {
            throw new VideoException(StatusCode.BAD_REQUEST);
        }
        return success(videoService.lookVideoByIdV3(lookVideoDto));
    }


    @PostMapping(value = "/up/{id}")
    public ResponseEntity<Response> upVideoById(@PathVariable Long id) {
        if (id == null || id <= 0) {
            throw new VideoException(StatusCode.BAD_REQUEST);
        }
        boolean ret = videoService.upVideoById(id);
        return success(ret);
    }

    @GetMapping(value = "/up/{id}")
    public ResponseEntity<Response> videoUpStatus(@PathVariable Long id) {
        if (id == null || id <= 0) {
            throw new VideoException(StatusCode.BAD_REQUEST);
        }
        boolean ret = videoService.videoUpStatus(id);
        return success(ret);
    }

    @DeleteMapping(value = "/up/{id}")
    public ResponseEntity<Response> removeUpVideo(@PathVariable Long id) {
        if (id == null || id <= 0) {
            throw new VideoException(StatusCode.BAD_REQUEST);
        }
        boolean ret = videoService.removeUpVideo(id);
        return success(ret);
    }

    @PostMapping(value = "/comment/{id}")
    public ResponseEntity<Response> commentVideoById(@PathVariable Long id, @RequestBody VideoCommentDto dto) {
        if (!CommonValidator.validate(dto) || id == null || id <= 0) {
            throw new VideoException(StatusCode.BAD_REQUEST);
        }
        Long commentId = videoService.commentVideoById(id, dto.getCommentId(), dto.getContent());
        return success(commentId);
    }

    @GetMapping(value = "/my/videos/{page}/{size}")
    public ResponseEntity<Response> myVideos(@PathVariable Integer page, @PathVariable Integer size) {
        page = GlobalController.checkPage(page, size);
        List<VideoInfo> videoList = videoService.getMyVideos(page, size);
        userFeignService.updateLastLoginTime();
        return success(videoList);
    }

    @GetMapping(value = "/my/looked/videos/{page}/{size}")
    public ResponseEntity<Response> myLokkerVideos(@PathVariable Integer page, @PathVariable Integer size) {
        page = GlobalController.checkPage(page, size);
        List<VideoInfo> videoList = videoService.getMyLookedVideos(page, size);
        return success(videoList);
    }

    @GetMapping(value = "/my/uped/videos/{page}/{size}")
    public ResponseEntity<Response> myUpedVideos(@PathVariable Integer page, @PathVariable Integer size) {
        page = GlobalController.checkPage(page, size);
        List<VideoInfo> videoList = videoService.getMyUpedVideos(page, size);
        return success(videoList);
    }

    @GetMapping(value = "/user/videos/{uid}/{page}/{size}")
    public ResponseEntity<Response> getUserVideos(@PathVariable Long uid, @PathVariable Integer page, @PathVariable Integer size) {
        if (uid == null || uid <= 0) {
            throw new VideoException(StatusCode.BAD_REQUEST);
        }
        page = GlobalController.checkPage(page, size);
        List<VideoInfo> videoList = videoService.getUserVideos(uid, page, size);
        return success(videoList);
    }


    @IgnoreSecurity
    @GetMapping(value = "/user/looked/video/{uid}/{page}/{size}")
    public ResponseEntity<Response> userLookVideoList(@PathVariable Long uid, @PathVariable Integer page, @PathVariable Integer size) {
        page = GlobalController.checkPage(page, size);
        List<VideoInfo> videoList = videoService.getUserLookedVideos(uid, page, size);
        return success(videoList);
    }

    /**
     * 用户点赞的视频
     *
     * @param uid
     * @param page
     * @param size
     * @return
     */
    @GetMapping(value = "/user/uped/list/{uid}/{page}/{size}")
    public ResponseEntity<Response> userUpVideoList(@PathVariable Long uid, @PathVariable Integer page, @PathVariable Integer size) {
        if (uid == null || uid <= 0) {
            throw new VideoException(StatusCode.BAD_REQUEST);
        }
        page = GlobalController.checkPage(page, size);
        List<VideoInfo> videoList = videoService.getUserUpedVideos(uid, page, size);
        return success(videoList);
    }

    @IgnoreSecurity
    @GetMapping(value = "/recommended/{deviceId}/{page}/{size}/{idNine}/{idTen}")
    public ResponseEntity<Response> recommendedVideoList(@PathVariable String deviceId,
                                                         @PathVariable Integer page, @PathVariable Integer size, @PathVariable Long idNine, @PathVariable Long idTen, HttpServletRequest request) throws Exception {

        String token = request.getHeader("ACCESS_TOKEN");
        String lat = request.getHeader("lat");
        String lng = request.getHeader("lng");
        page = GlobalController.checkPage(page, size);
        List<VideoInfo> videoList = videoService.recomendedVideoList2(deviceId, page, size, idNine, idTen, token);
        userFeignService.updateLastLoginTime();
        LocalUserInfo info = LocalUser.getUser();
        if (info != null) {
            BaseMqSendModel baseMqSendModel = new BaseMqSendModel("UpdateLocation");
            baseMqSendModel.setTag(MqTag.USER);
            baseMqSendModel.setSendContentBean(lat + "," + lng + "," + info.getUser().getId());
            RocketMqUtil.send(baseMqSendModel);

        }
        return success(videoList);
    }

    /**
     * 获取视频信息
     * @param deviceId
     * @param page
     * @param size
     * @param idNine
     * @param idTen
     * @param request
     * @return
     * @throws Exception
     */
    @GetMapping(value = "/recommended/v3/{deviceId}/{page}/{size}/{idNine}/{idTen}")
    @IgnoreSecurity
    public ResponseEntity<Response> recommendedVideoListv3(@PathVariable String deviceId,
                                                           @PathVariable Integer page, @PathVariable Integer size, @PathVariable Long idNine, @PathVariable Long idTen, HttpServletRequest request) throws Exception {

        page = GlobalController.checkPage(page, size);
        RecommendVideoDto dto = new RecommendVideoDto();
        dto.setDeviceId(deviceId);
        dto.setPage(page);
        List<VideoInfo> video_list = recommendVideoService.recomendedVideoList(dto);
        LocalUserInfo info = LocalUser.getUser();
        if (info != null) {
            String lat = request.getHeader("lat");
            String lng = request.getHeader("lng");
            BaseMqSendModel baseMqSendModel = new BaseMqSendModel("UpdateLocation");
            baseMqSendModel.setTag(MqTag.USER);
            baseMqSendModel.setSendContentBean(lat + "," + lng + "," + info.getUser().getId());
            RocketMqUtil.send(baseMqSendModel);

        }
        if (StringUtils.isNotBlank(request.getHeader("ACCESS_TOKEN"))) {
            try {
                userFeignService.updateLastLoginTime();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return success(video_list);
    }


    @IgnoreSecurity
    @GetMapping(value = "/near/{longitude}/{latitude}/{page}/{size}")
    public ResponseEntity<Response> nearVideoList(@PathVariable String longitude, @PathVariable String latitude, @PathVariable Integer page, @PathVariable Integer size) {
        Double[] point = new Double[2];
        point[0] = Double.parseDouble(longitude);
        point[1] = Double.parseDouble(latitude);
        if (point[0] == 0 && point[1] == 0) {
            return success(new ArrayList<VideoInfo>());
        } else {
            logger.info("请求的地理坐标信息: lng: " + point[0] + " lat: " + point[1]);
            return success(videoService.findNearVideoList(point, page, size));
        }
    }

    /**
     * 获取"谁看过我视频" 人的列表
     *
     * @param longitude
     * @param latitude
     * @param page
     * @param size
     * @return
     */
    @GetMapping(value = "/my/whoSawMe/{longitude}/{latitude}/{page}/{size}")
    public ResponseEntity<Response> whoSawMe(@PathVariable String longitude, @PathVariable String latitude, @PathVariable Integer page, @PathVariable Integer size) {
        page = GlobalController.checkPage(page, size);
        if (StringUtils.isEmpty(longitude) || StringUtils.isEmpty(latitude)) {
            throw new VideoException(StatusCode.BAD_REQUEST);
        }
        // 判断经纬度是否是数字
        try {
            Double.parseDouble(latitude);
            Double.parseDouble(longitude);
        } catch (Exception e) {
            throw new VideoException(StatusCode.BAD_REQUEST);
        }
        List<VideoWhoSawMeInfo> videoList = videoService.whoSawMe(longitude, latitude, page, size);
        return success(videoList);
    }

    /**
     * 我收藏的视频
     *
     * @param page
     * @param size
     * @return
     */
    @GetMapping(value = "/my/collect/videos/{page}/{size}")
    public ResponseEntity<Response> myCollectVideos(@PathVariable Integer page, @PathVariable Integer size) {
        page = GlobalController.checkPage(page, size);
        List<VideoInfo> videoList = videoService.getMyCollectVideos(page, size);
        return success(videoList);
    }

    /**
     * 收藏视频
     *
     * @return
     */
    @GetMapping(value = "/collect/video/{videoid}")
    public ResponseEntity<Response> collectVideo(@PathVariable Long videoid) {
        if (videoid == null || videoid <= 0) {
            throw new VideoException(StatusCode.BAD_REQUEST);
        }
        boolean flag = videoService.collectVideo(videoid);
        return success(flag);
    }

    /**
     * 取消收藏
     */

    @GetMapping(value = "/cancel/collect/{videoid}")
    public ResponseEntity<Response> cancelCollect(@PathVariable Long videoid) {
        if (videoid == null || videoid <= 0) {
            throw new VideoException(StatusCode.BAD_REQUEST);
        }
        boolean flag = videoService.cancelCollect(videoid);
        return success(flag);
    }

    /**
     * 查询所有
     */

    @GetMapping(value = "/getAll")
    @IgnoreSecurity
    @Deprecated
    public ResponseEntity<Response> getAll() {
        List<VideoInfo> videoList = videoService.getAll();
        return success(videoList);
    }

    /**
     * 获取评论列表
     *
     * @return
     */
    @GetMapping(value = "/comments/{videoId}/{page}/{size}")
    @IgnoreSecurity
    public ResponseEntity<Response> getCommentList(@PathVariable Long videoId, @PathVariable Integer page, @PathVariable Integer size) {
        if (videoId == null || videoId <= 0) {
            throw new VideoException(StatusCode.BAD_REQUEST);
        }
        page = GlobalController.checkPage(page, size);
        List<VideoComment> commentList = videoService.getComments(videoId, page, size);
        return success(commentList);
    }

    /**
     * 获取视频的评论数量
     *
     * @return
     */
    @GetMapping(value = "/commentsCount/{videoId}")
    @IgnoreSecurity
    public ResponseEntity<Response> getCommentoCount(@PathVariable Long videoId) {
        if (videoId == null || videoId <= 0) {
            throw new VideoException(StatusCode.BAD_REQUEST);
        }
        return success(videoService.getCommentsCount(videoId));
    }

    /**
     * 关注者的视频
     *
     * @param dto
     * @return
     */
    @PostMapping(value = "/concern")
    public ResponseEntity<Response> getVideoInfoByUserIdList(@RequestBody VideoQueryDto dto) {
        if (!CommonValidator.validate(dto)) {
            throw new VideoException(StatusCode.BAD_REQUEST);
        }
        return success(videoService.getVideoInfoByUserIdList(dto));
    }

    /**
     * 分享视频
     *
     * @param dto
     * @return
     */
    @PostMapping(value = "/share")
    @IgnoreSecurity
    public ResponseEntity<Response> shareVideo(@RequestBody ShareVideoDto dto) {
        if (!CommonValidator.validate(dto)) {
            throw new VideoException(StatusCode.BAD_REQUEST);
        }
        return success(videoService.shareVideo(dto));
    }

    /**
     * 删除视频评论
     *
     * @param id
     * @param vid
     * @return
     */
    @DeleteMapping(value = "/delete/video/comment/{id}/{vid}")
    public ResponseEntity<Response> deleteComment(@PathVariable Long id, @PathVariable Long vid) {
        return success(videoService.deleteComment(id, vid));
    }

    /**
     * 删除视频
     *
     * @param id
     * @return
     */
    @DeleteMapping(value = "/delete/{id}")
    public ResponseEntity<Response> deleteVideoById(@PathVariable Long id) {
        return success(videoService.deleteVideoById(id));
    }

    /**
     * 根据videoids 查询数据
     *
     * @param videoIds
     * @return
     */
    @RequestMapping(value = "/getUpByVideoId", method = RequestMethod.GET)
    public ResponseEntity<Response> getUpByVideoId(@RequestParam(value = "userId", required = false) Long userId, @RequestParam(value = "ids", required = false) List<Long> videoIds) {
        List<Long> list = null;
        if (videoIds != null && !videoIds.isEmpty()) {
            list = videoService.getUpByVideoId(userId, videoIds);
        }

        return success(list);

    }

    @IgnoreSecurity
    @GetMapping("/info/watermark/{id}")
    public ResponseEntity<Response> getVideoWithWatermark(@PathVariable Long id) {
        if (id == null || id <= 0) {
            throw new VideoException(StatusCode.BAD_REQUEST);
        }
        return success(videoService.getVideoWithWatermarkById(id));
    }

    /**
     * @param videoId
     * @param waterMarkUrl
     * @return
     */
    @PostMapping(value = "/update/VideoWaterMark")
    public ResponseEntity<Response> updateVideoWaterMarkUrl(@RequestParam("id") Long videoId, @RequestParam("url") String waterMarkUrl) {
        if (videoId == null || videoId <= 0 || StringUtils.isBlank(waterMarkUrl) || waterMarkUrl.length() < 30) {
            throw new VideoException(StatusCode.BAD_REQUEST);
        }
        return success(videoService.updateVideoWaterMarkUrl(videoId, waterMarkUrl));
    }

    /**
     * 管理员加水印接口
     *
     * @param videoId
     * @param waterMarkUrl
     * @param musicUrl
     * @param userId
     * @return
     */
    @IgnoreSecurity
    @RequestMapping(value = "/private/update/VideoWaterMark", method = RequestMethod.POST)
    public ResponseEntity<Response> updateVideoWaterMarkUrl(@RequestParam("videoId") Long videoId, @RequestParam("video") String waterMarkUrl,
                                                            @RequestParam("music") String musicUrl, @RequestParam("userId") Long userId) {
        if (videoId == null || videoId <= 0 || StringUtils.isBlank(waterMarkUrl) || waterMarkUrl.length() < 30) {
            throw new VideoException(StatusCode.BAD_REQUEST);
        }
        videoService.updateVideoWaterMarkUrl(videoId, waterMarkUrl);
        if (StringUtils.isNotBlank(musicUrl) && userId != null && userId > 0) {
            musicService.updateMusicOrginalMusicUrl(videoId, userId, musicUrl);
        }
        return success(true);
    }

    /**
     * 管理员加水印接口
     *
     * @param videoId
     * @param waterMarkUrl
     * @param musicUrl
     * @param userId
     * @return
     */
    @IgnoreSecurity
    @RequestMapping(value = "/private/update/VideoWaterMark/v1", method = RequestMethod.POST)
    public ResponseEntity<Response> updateVideoWaterMarkUrlV1(@RequestParam("videoId") Long videoId, @RequestParam("video") String waterMarkUrl,
                                                              @RequestParam("music") String musicUrl, @RequestParam("userId") Long userId, @RequestParam("duration") Double duration) {
        if (videoId == null || videoId <= 0 || StringUtils.isBlank(waterMarkUrl) || waterMarkUrl.length() < 30) {
            throw new VideoException(StatusCode.BAD_REQUEST);
        }
        videoService.updateVideoWaterMarkUrl(videoId, waterMarkUrl);
        if (StringUtils.isNotBlank(musicUrl) && userId != null && userId > 0) {
            musicService.updateMusicOrginalMusicUrlV1(videoId, userId, musicUrl, duration);
        }
        return success(true);
    }

    /**
     * 获取主页的个人视频和喜欢视频的数量
     *
     * @return
     */
    @IgnoreSecurity
    @RequestMapping(value = "/homepageVideoCount/{userId}", method = RequestMethod.GET)
    public ResponseEntity<Response> getHomepageVideoCount(@PathVariable("userId") Long userId) {
        return success(videoService.getHomepageVideoCount(userId));
    }

    /**
     * 获取拍同款音乐基本信息
     * add by kml 2018/10/18
     *
     * @return
     */
    @RequestMapping(value = "/sameMusicDetail/{musicId}", method = RequestMethod.GET)
    public ResponseEntity<Response> sameMusicDetail(@PathVariable Long musicId) {
        if (musicId == null) {
            throw new MusicException(StatusCode.MUSIC_EXCEPTION);
        }
        return success(videoService.sameMusicDetail(musicId));
    }

    /**
     * 获取拍同款音乐的视频
     * add by kml 2018/10/18
     *
     * @return
     */
    @RequestMapping(value = "/getVideoInSameMusic/{musicId}/{page}/{size}", method = RequestMethod.GET)
    public ResponseEntity<Response> getVideoInSameMusic(@PathVariable Long musicId,
                                                        @PathVariable Integer page, @PathVariable Integer size) {
        if (musicId == null) {
            throw new MusicException(StatusCode.MUSIC_EXCEPTION);
        }
        page = GlobalController.checkPage(page, size);
        return success(videoService.getVideoInSameMusic(musicId, page, size));
    }

    /**
     * 批量加水印接口
     *
     * @param addWaterMarkDto
     * @return
     */
    @IgnoreSecurity
    @PostMapping(value = "/private/admin/add/watermark")
    public ResponseEntity<Response> syncDataForAddWaterMark(@RequestBody AddWaterMarkDto addWaterMarkDto) {
        if (addWaterMarkDto.getStartId() == null || addWaterMarkDto.getEndId() == null || addWaterMarkDto.getStartId() <= 0
                || addWaterMarkDto.getEndId() <= 0 || addWaterMarkDto.getStartId() > addWaterMarkDto.getEndId()) {
            throw new VideoException(StatusCode.BAD_REQUEST);
        }
        videoService.syncDataForAddWaterMark(addWaterMarkDto.getStartId(), addWaterMarkDto.getEndId());
        return success(true);
    }

    @IgnoreSecurity
    @GetMapping(value = "/lookNumber/{videoId}")
    public ResponseEntity<Response> lookNumber(@PathVariable("videoId") Long videoId ){
        return success(videoService.lookNumber(videoId));
    }
}
